package com.framework.config.advice;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.framework.config.datasource.DataSourceContextHolder;
import com.framework.stereotype.DataSource;

@Component
@Aspect
@Order(value=1)
public class GetDataSourceAspect implements InitializingBean {
	private static final Logger logger = LoggerFactory.getLogger(GetDataSourceAspect.class);

	private final String POINT_CUT = "execution(* com.*.service.impl.*ServiceImpl.*(..))";

	@Before(POINT_CUT)
	private void doGetDatasourceType(JoinPoint joinPoint) throws Throwable {
		logger.debug("GetDataSourceAspect setDataSourceType");
		// Annotation을 읽어 들이기 위해 현재의 method를 읽어 들인다.
		final String methodName = joinPoint.getSignature().getName();
		final MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		Method method = methodSignature.getMethod();
		if (method.getDeclaringClass().isInterface()) {
			method = joinPoint.getTarget().getClass().getDeclaredMethod(methodName, method.getParameterTypes());
		}
		// Annotation을 가져온다.
		DataSource dataSource = method.getAnnotation(DataSource.class);
		if(null == dataSource){
			dataSource = joinPoint.getTarget().getClass().getAnnotation(DataSource.class);
		}
		if (null != dataSource) {
			// Method에 해당 dataSource관련 설정이 있을 경우 해당 dataSource의 value를 읽어 들인다.
			DataSourceContextHolder.setDataSourceType(dataSource.value());
		}
		logger.debug("GetDataSourceAspect Get DataSource : " + DataSourceContextHolder.getDataSourceType());

	}

	@After(POINT_CUT)
	private void doClearDatasourceType(JoinPoint joinPoint) throws Throwable {
		DataSourceContextHolder.clearDataSourceType();
		logger.debug("GetDataSourceAspect clearDataSourceType");
	}
	@Override
	public void afterPropertiesSet() throws Exception {

	}
}
